//------------------------------------------------------------
//  Filename: voltage_proc.v
//   
//  Author  : wlduan@gmail.com
//  Revise  : 2017-03-20 11:47
//  Description: 
//   
//  Copyright (C) 2014, YRBD, Inc. 					      
//  All Rights Reserved.                                       
//-------------------------------------------------------------
//
`timescale 1ns/1ps
 
module VOLTAGE_PROC ( 
    input wire        clk,  
    input wire        rst, 
     
    input wire        xadc_init,     
    input wire        vp_in,
    input wire        vn_in, 
    input wire        tp_in,
    input wire        tn_in, 

    output reg [15:0] temp_value,
    output reg [15:0] vpin_value,
    output reg [15:0] vtmp_value,
    output reg [15:0] vint_value,
    output reg [15:0] vaux_value
);  
//--------------------------------------------------------
wire        dclk_in  = clk;
wire        reset_in = rst;
//--------------------------------------------------------
reg [7:0]   state;
reg [1:0]   den_reg;
reg [1:0]   dwe_reg;
reg [15:0]  di_drp;
wire[15:0]  do_drp;
reg [6:0]   daddr;
reg [7:0]   wr_cnt;
//--------------------------------------------------------
wire        busy_out;
wire [4:0]  channel_out;
wire        drdy_out;
wire        eoc_out;
wire        eos_out;
wire        alarm_out; 
// axi4stream master signals 
wire        s_axis_aclk = clk;
wire        m_axis_aclk = clk;
wire        m_axis_resetn = ~rst;
wire[15:0]  m_axis_tdata;
wire[4 :0]  m_axis_tid;
wire        m_axis_tvalid;
reg         m_axis_tready;
//--------------------------------------------------------
wire        den_in  = den_reg[0];
wire        dwe_in  = dwe_reg[0];
//--------------------------------------------------------
wire [22:0] INIT[26:0];
//--------------------------------------------------------
assign INIT[ 0] = {7'h40,16'h2000}; // config reg 0
assign INIT[ 1] = {7'h41,16'h21AF}; // config reg 1
assign INIT[ 2] = {7'h42,16'h0400}; // config reg 2
assign INIT[ 3] = {7'h48,16'h0F01}; // Sequencer channel selection
assign INIT[ 4] = {7'h49,16'h0004}; // Sequencer channel selection,enable chnl #2
assign INIT[ 5] = {7'h4A,16'h0F00}; // Sequencer Average selection
assign INIT[ 6] = {7'h4B,16'h0004}; // Sequencer Average selection
assign INIT[ 7] = {7'h4C,16'h0000}; // Sequencer Bipolar selection
assign INIT[ 8] = {7'h4D,16'h0000}; // Sequencer Bipolar selection
assign INIT[ 9] = {7'h4E,16'h0000}; // Sequencer Acq time selection
assign INIT[10] = {7'h4F,16'h0000}; // Sequencer Acq time selection
assign INIT[11] = {7'h50,16'hB5ED}; // Temp alarm trigger
assign INIT[12] = {7'h51,16'h57E4}; // Vccint upper alarm limit
assign INIT[13] = {7'h52,16'hA147}; // Vccaux upper alarm limit
assign INIT[14] = {7'h53,16'hCA33}; // Temp alarm OT upper
assign INIT[15] = {7'h54,16'hA93A}; // Temp alarm reset
assign INIT[16] = {7'h55,16'h52C6}; // Vccint lower alarm limit
assign INIT[17] = {7'h56,16'h9555}; // Vccaux lower alarm limit
assign INIT[18] = {7'h57,16'hAE4E}; // Temp alarm OT reset
assign INIT[19] = {7'h58,16'h5999}; // VCCBRAM upper alarm limit
assign INIT[20] = {7'h5C,16'h5111}; //  VCCBRAM lower alarm limit
assign INIT[21] = {7'h59,16'h5555}; // VCCPINT upper alarm limit
assign INIT[22] = {7'h5D,16'h5111}; //  VCCPINT lower alarm limit
assign INIT[23] = {7'h5A,16'h9999}; // VCCPAUX upper alarm limit
assign INIT[24] = {7'h5E,16'h91EB}; //  VCCPAUX lower alarm limit
assign INIT[25] = {7'h5B,16'h6AAA}; // VCCDdro upper alarm limit
assign INIT[26] = {7'h5F,16'h6666}; //  VCCDdro lower alarm limit
//--------------------------------------------------------
reg  [15:0] MEASURED_TEMP;
reg  [15:0] MEASURED_VCCINT;
reg  [15:0] MEASURED_VPIN;
reg  [15:0] MEASURED_VCCAUX;
reg  [15:0] MEASURED_VTMP;
//--------------------------------------------------------
localparam  INIT_READ      = 8'd01;
localparam  WRITE_REGS     = 8'd02;
localparam  WRITE_WAITDRDY = 8'd03;
localparam  READ_REG03     = 8'd04;
localparam  REG03_WAITDRDY = 8'd05;
localparam  READ_REG02     = 8'd06;
localparam  REG02_WAITDRDY = 8'd07;
localparam  READ_REG01     = 8'd08;
localparam  REG01_WAITDRDY = 8'd09;
localparam  READ_REG00     = 8'd10;
localparam  REG00_WAITDRDY = 8'd11;
localparam  READ_REG12     = 8'd12;
localparam  REG12_WAITDRDY = 8'd13;
//--------------------------------------------------------
always @(posedge clk) begin
    if (xadc_init|rst) begin
        state   <= INIT_READ;
        den_reg <= 2'h0;
        dwe_reg <= 2'h0;
        wr_cnt  <= 8'b0;
        di_drp  <= 16'h0000;
    end
    else begin
        case (state)
            INIT_READ : begin
                daddr   <= 7'h40;
                den_reg <= 2'h0; 
                wr_cnt  <= 8'b0;
                if(busy_out == 0) state <= WRITE_REGS;
            end
            WRITE_REGS: begin
                daddr   <= INIT[wr_cnt][22:16];
                di_drp  <= INIT[wr_cnt][15:0];
                wr_cnt  <= wr_cnt + 1;
                den_reg <= 2'h2;
                dwe_reg <= 2'h2;
                state   <= WRITE_WAITDRDY;
            end
            WRITE_WAITDRDY: begin
                if(wr_cnt > 26) begin
                    state  <= READ_REG03; 
                end
                else if(drdy_out == 1) begin
                    state  <= WRITE_REGS; 
                end
                else begin  // performing write
                    den_reg <= {1'b0,den_reg[1]};
                    dwe_reg <= {1'b0,dwe_reg[1]};
                end
            end
            READ_REG03 : begin
                daddr   <= 7'h03;
                den_reg <= 2'h2; // performing read
                if (eos_out == 1) state <= REG03_WAITDRDY;
            end
            REG03_WAITDRDY : begin
                if (drdy_out ==1) begin
                    MEASURED_VPIN  <= do_drp;
                    state          <= READ_REG02;
                end
                else begin
                    den_reg <= { 1'b0, den_reg[1] } ;
                    dwe_reg <= { 1'b0, dwe_reg[1] } ;                    
                    state   <= state;
                end
            end
            READ_REG02 : begin
                daddr   <= 7'h02;
                den_reg <= 2'h2; // performing read
                state   <= REG02_WAITDRDY;
            end
            REG02_WAITDRDY : begin
                if (drdy_out ==1) begin
                    MEASURED_VCCAUX  <= do_drp;
                    state            <= READ_REG01;
                end
                else begin
                    den_reg <= { 1'b0, den_reg[1] } ;
                    dwe_reg <= { 1'b0, dwe_reg[1] } ;
                    state   <= state;
                end
            end
            READ_REG01 : begin
                daddr   <= 7'h01;
                den_reg <= 2'h2; // performing read
                state   <= REG01_WAITDRDY;
            end
            REG01_WAITDRDY : begin
                if (drdy_out ==1) begin
                    MEASURED_VCCINT <= do_drp;
                    state           <= READ_REG00;
                end
                else begin
                    den_reg <= { 1'b0, den_reg[1] } ;
                    dwe_reg <= { 1'b0, dwe_reg[1] } ;
                    state   <= state;
                end
            end
            READ_REG00 : begin
                daddr   <= 7'h00;
                den_reg <= 2'h2; // performing read
                state   <= REG00_WAITDRDY;
            end
            REG00_WAITDRDY : begin
                if (drdy_out ==1) begin
                    MEASURED_TEMP <= do_drp;
                    state         <= READ_REG12;
                end
                else begin
                    den_reg <= { 1'b0, den_reg[1] } ;
                    dwe_reg <= { 1'b0, dwe_reg[1] } ;
                    state   <= state;
                end
            end
            READ_REG12 : begin
                daddr   <= 7'h12;
                den_reg <= 2'h2; // performing read
                state   <= REG12_WAITDRDY;
            end
            REG12_WAITDRDY :
                if (drdy_out ==1) begin
                    MEASURED_VTMP <= do_drp;
                    state         <= READ_REG03;
                end
                else begin
                    den_reg       <= { 1'b0, den_reg[1] } ;
                    dwe_reg       <= { 1'b0, dwe_reg[1] } ;
                    state         <= state;
                end            
        endcase
    end
end

//--------------------------------------------------------
always @(posedge clk ) temp_value  <= MEASURED_TEMP;  
always @(posedge clk ) vint_value  <= MEASURED_VCCINT;
always @(posedge clk ) vpin_value  <= MEASURED_VPIN;  
always @(posedge clk ) vaux_value  <= MEASURED_VCCAUX;
always @(posedge clk ) vtmp_value  <= MEASURED_VTMP;
//always @(posedge clk ) m_axis_tready <= m_axis_tvalid;
//--------------------------------------------------------
xadc_wiz_0 adc_inst0( 
    .dclk_in     ( dclk_in     ) ,
    .reset_in    ( reset_in    ) ,

    .den_in      ( den_in      ) ,
    .dwe_in      ( dwe_in      ) ,
    .di_in       ( di_drp      ) ,
    .do_out      ( do_drp      ) ,
    .daddr_in    ( daddr       ) ,
    
    .vp_in       ( vp_in       ) ,
    .vn_in       ( vn_in       ) ,
    .vauxp2      ( tp_in       ) ,  
    .vauxn2      ( tn_in       ) ,  
    .busy_out    ( busy_out    ) ,
    .channel_out ( channel_out ) ,
    .drdy_out    ( drdy_out    ) ,
    .eoc_out     ( eoc_out     ) ,
    .eos_out     ( eos_out     ) ,
    .alarm_out   ( alarm_out   )
);

endmodule
